from tkinter import *
import ttkbootstrap as ttk
from PIL import ImageTk
import webbrowser
import base64
import os

from backend.CalculateDistance import calculate_distance
from backend.CalculateVoltage import calculate_voltage
from frontend import image


class DieletricCalculator:
    def __init__(self):
        self.window=ttk.Window()
        self.window.title('电介质强度计算器')

        self.pollution_class_var = IntVar()  # 污染等级
        self.material_var = IntVar()         # 材料组
        self.object_type_var = IntVar()      # 对象类型
        self.place_type_var = IntVar()       # 部位
        self.multiple_num_var = IntVar()     # 重数
        self.voltage_type_var = IntVar()     # 电流类型
        self.peak_voltage_entry_textvar = StringVar()    # 工作电压字符串
        self.supply_voltage_entry_textvar = StringVar()  # 网电源供电电压字符串
        self.altitude_entry_textvar = StringVar()        # 海拔字符串

        # 设置默认值
        self.pollution_class_var.set(1)
        self.material_var.set(3)
        self.object_type_var.set(0)
        self.place_type_var.set(0)
        self.multiple_num_var.set(0)
        self.voltage_type_var.set(1)
        self.peak_voltage_entry_textvar.set('220')
        self.supply_voltage_entry_textvar.set('2000')
        self.altitude_entry_textvar.set('220')

        self.InitLogo()
        self.CreatWidget()
        self.PlaceWidget()


    def launch(self):
        self.dis_on_screen_center()
        self.window.mainloop()


    def dis_on_screen_center(self):
        # 屏幕宽度和高度
        self.screen_width = self.window.winfo_screenwidth()
        self.screen_height = self.window.winfo_screenheight()

        # 计算窗口在屏幕中央的位置坐标
        cx = (self.screen_width - self.window.winfo_reqwidth()*2) // 2
        cy = (self.screen_height - self.window.winfo_reqheight()*2) // 2

        self.window.geometry(f"{self.win_width}x{self.win_height}+{cx}+{cy}")
        self.window.resizable(0,0)


    def InitLogo(self):
        with open(r"temp_win_logo.ico",'wb') as f:
            temp_img = base64.b64decode(image.DieletricCalculator_logo)
            f.write(temp_img)
        self.window.iconbitmap(r"temp_win_logo.ico")   # 更改窗口图标
        os.remove(r"temp_win_logo.ico")
        
        with open(r"temp_institution_logo.png",'wb') as f:
            temp_img = base64.b64decode(image.institution_logo)
            f.write(temp_img)
        self.institution_ico = ImageTk.PhotoImage(file=r"temp_institution_logo.png")
        os.remove(r"temp_institution_logo.png")


    def CreatWidget(self):
        """ 创建控件 """
        # 窗口标题
        self.window_title = Label(self.window, text="电介质强度计算器", font=("华文行楷", 20))
        # 药检院logo
        self.institution_logo= Label(self.window, image=self.institution_ico)
        # 污染等级
        self.pollution_class_label = Label(self.window, text='污染等级',font=("隶书", 14))
        self.pollution_class_rad1 = Radiobutton(self.window, text='1', value=0, variable=self.pollution_class_var, font=("华文新魏", 12))
        self.pollution_class_rad2 = Radiobutton(self.window, text='2', value=1, variable=self.pollution_class_var, font=("华文新魏", 12))
        self.pollution_class_rad3 = Radiobutton(self.window, text='3', value=2, variable=self.pollution_class_var, font=("华文新魏", 12))
        # 材料组
        self.material_label = Label(self.window, text='材料组',font=("隶书", 14))
        self.material_var_rad1 = Radiobutton(self.window, text='Ⅰ', value=0, variable=self.material_var, font=("华文新魏", 12))
        self.material_var_rad2 = Radiobutton(self.window, text='Ⅱ', value=1, variable=self.material_var, font=("华文新魏", 12))
        self.material_var_rad3 = Radiobutton(self.window, text='Ⅲa', value=2, variable=self.material_var, font=("华文新魏", 12))
        self.material_var_rad4 = Radiobutton(self.window, text='Ⅲb', value=3, variable=self.material_var, font=("华文新魏", 12))
        # 类型
        self.object_type_label = Label(self.window, text='类型',font=("隶书", 14))
        self.object_type_rad1 = Radiobutton(self.window, text="MOOP", value=0, variable=self.object_type_var, font=("华文新魏", 12))
        self.object_type_rad2 = Radiobutton(self.window, text="MOPP",   value=1, variable=self.object_type_var, font=("华文新魏", 12))
        # 部位
        self.place_type_label = Label(self.window, text='部位',font=("隶书", 14))
        self.place_type_rad1 = Radiobutton(self.window, text="网电源",   value=0, variable=self.place_type_var, font=("华文新魏", 12))
        self.place_type_rad2 = Radiobutton(self.window, text="次级电路", value=1, variable=self.place_type_var, font=("华文新魏", 12))
        # 重数
        self.multiple_num_label = Label(self.window, text='重数',font=("隶书", 14))
        self.multiple_num_rad1 = Radiobutton(self.window, text="一重", value=0, variable=self.multiple_num_var, font=("华文新魏", 12))
        self.multiple_num_rad2 = Radiobutton(self.window, text="两重", value=1, variable=self.multiple_num_var, font=("华文新魏", 12))
        # 电流类型
        self.voltage_type_label = Label(self.window, text='电压',font=("隶书", 14))
        self.voltage_type_rad1 = Radiobutton(self.window, text="直流", value=0, variable=self.voltage_type_var, font=("华文新魏", 12))
        self.voltage_type_rad2 = Radiobutton(self.window, text="交流", value=1, variable=self.voltage_type_var, font=("华文新魏", 12))
        # 峰值
        self.peak_voltage_entry_label = Label(self.window, text="工作电压(Vrms):",font=("隶书", 14))
        self.peak_voltage_entry = Entry(self.window, width=10, relief='groove', bd=5, highlightcolor='red', font=("华文新魏", 12), textvariable=self.peak_voltage_entry_textvar)
        # 海拔
        self.altitude_entry_label = Label(self.window, text="海拔(m):", font=("隶书", 14))
        self.altitude_entry = Entry(self.window, width=10, relief='groove', bd=5, highlightcolor='red', font=("华文新魏", 12), textvariable=self.supply_voltage_entry_textvar)
        # 标称网电源电压
        self.supply_voltage_entry_label = Label(self.window, text="标称网电源电压(Vrms)(若无网电源则填0):",font=("隶书", 14))
        self.supply_voltage_entry = Entry(self.window, width=12, relief='groove', bd=5, highlightcolor='red', font=("华文新魏", 12), textvariable=self.altitude_entry_textvar)
        # 计算结果
        self.cal_voltage_label = Label(self.window, text="", font=("Time", 14))
        # 计算按键
        self.calbtn = Button(self.window, text="    开始计算    ", command=self.ClickCalButton, relief='raised', padx=20, pady=5, font=("隶书", 14))
        # 窗口信息
        self.window_info = Label(self.window, text="GB 9706.1-2020", font=("Arial Bold", 10),justify='right')
        # 开源地址
        self.address = Button(self.window, text="开源地址", font=("Arial Bold", 10), command=self.ClickLinkButton, relief='raised')
        self.address.configure(background='white',fg='black')


    def PlaceWidget(self):
        """ 参考尺寸 """
        w0 = self.window_title.winfo_reqwidth()
        w1 = self.pollution_class_label.winfo_reqwidth()
        w2 = self.object_type_rad1.winfo_reqwidth() *1.5
        w3 = self.peak_voltage_entry_label.winfo_reqwidth()
        w4 = self.peak_voltage_entry.winfo_reqwidth()
        w5 = self.altitude_entry_label.winfo_reqwidth()
        w6 = self.supply_voltage_entry_label.winfo_reqwidth()
        w7 = self.material_var_rad4.winfo_reqwidth()

        h1 = self.window_title.winfo_reqheight()*1.5
        h2 = self.pollution_class_label.winfo_reqheight() *1.5
        h3 = self.calbtn.winfo_reqheight()

        self.win_height =  int(2*h1+8*h2+h3*3+h3*3)
        self.win_width = int(max(30+2*w1+3*w2+w7, max(30+w3+w4*1.5, 30+2*w1+w2)+w5)) + 30

        """ 绝对界面排布 """
        self.window_title.place(x=self.win_width//2, y=h1, anchor='center')
        self.window_info.pack(side="right",anchor='s')
        self.institution_logo.place(x=self.win_width//2-w0//2, y=h1, anchor='e')
        # 污染等级
        self.pollution_class_label.place(x=30, y=2*h1)
        self.pollution_class_rad1.place(x=30+2*w1, y=2*h1)
        self.pollution_class_rad2.place(x=30+2*w1+w2, y=2*h1)
        self.pollution_class_rad3.place(x=30+2*w1+2*w2, y=2*h1)
        # 材料组
        self.material_label.place(x=30, y=2*h1+h2)
        self.material_var_rad1.place(x=30+2*w1, y=2*h1+h2)
        self.material_var_rad2.place(x=30+2*w1+w2, y=2*h1+h2)
        self.material_var_rad3.place(x=30+2*w1+2*w2, y=2*h1+h2)
        self.material_var_rad4.place(x=30+2*w1+3*w2, y=2*h1+h2)
        # 类型
        self.object_type_label.place(x=30, y=2*h1+2*h2)
        self.object_type_rad1.place(x=30+2*w1, y=2*h1+2*h2)
        self.object_type_rad2.place(x=30+2*w1+w2, y=2*h1+2*h2)
        # 部位
        self.place_type_label.place(x=30, y=2*h1+3*h2)
        self.place_type_rad1.place(x=30+2*w1, y=2*h1+3*h2)
        self.place_type_rad2.place(x=30+2*w1+w2, y=2*h1+3*h2)
        # 重数
        self.multiple_num_label.place(x=30, y=2*h1+4*h2)
        self.multiple_num_rad1.place(x=30+2*w1, y=2*h1+4*h2)
        self.multiple_num_rad2.place(x=30+2*w1+w2, y=2*h1+4*h2)
        # 电流类型
        self.voltage_type_label.place(x=30, y=2*h1+5*h2)
        self.voltage_type_rad1.place(x=30+2*w1, y=2*h1+5*h2)
        self.voltage_type_rad2.place(x=30+2*w1+w2, y=2*h1+5*h2)
        # 基准电压
        self.peak_voltage_entry_label.place(x=30, y=2*h1+6*h2)
        self.peak_voltage_entry.place(x=30+w3, y=2*h1+6*h2)
        # 海拔
        self.altitude_entry_label.place(x=max(30+w3+w4*1.5, 30+2*w1+w2), y=2*h1+6*h2)
        self.altitude_entry.place(x=max(30+w3+w4*1.5, 30+2*w1+w2)+w5, y=2*h1+6*h2)
        # 标称网电源电压
        self.supply_voltage_entry_label.place(x=30, y=2*h1+7*h2)
        self.supply_voltage_entry.place(x=30+w6, y=2*h1+7*h2)
        # 开始计算按键
        self.calbtn.place(x=self.win_width//2, y=2*h1+8*h2+h3, anchor='center')
        # 开源地址
        self.address.pack(side="left",anchor='s')
        # 计算结果显示窗
        self.cal_voltage_label.place(x=self.win_width//2, y=2*h1+8*h2+h3*3, anchor='center')




        # """ 相对界面排布 """
        # self.window_title.place(relx=0.5, rely=0.05, anchor='center', height=100)
        # self.window_info.pack(side="right",anchor='s')
        # self.institution_logo.place(relx=0.05, rely=0.05, anchor='center')
        # # 污染等级
        # self.pollution_class_label.place(relx=0.1, rely=0.1)
        # self.pollution_class_rad1.place(relx=0.33, rely=0.1)
        # self.pollution_class_rad2.place(relx=0.48, rely=0.1)
        # self.pollution_class_rad3.place(relx=0.66, rely=0.1)
        # # 材料组
        # self.material_label.place(relx=0.1, rely=0.16)
        # self.material_var_rad1.place(relx=0.33, rely=0.16)
        # self.material_var_rad2.place(relx=0.42, rely=0.16)
        # self.material_var_rad3.place(relx=0.54, rely=0.16)
        # self.material_var_rad4.place(relx=0.66, rely=0.16)
        # # 类型
        # self.object_type_label.place(relx=0.1, rely=0.22)
        # self.object_type_rad1.place(relx=0.33, rely=0.22)
        # self.object_type_rad2.place(relx=0.66, rely=0.22)
        # # 部位
        # self.place_type_label.place(relx=0.1, rely=0.28)
        # self.place_type_rad1.place(relx=0.33, rely=0.28)
        # self.place_type_rad2.place(relx=0.66, rely=0.28)
        # # 重数
        # self.multiple_num_label.place(relx=0.1, rely=0.34)
        # self.multiple_num_rad1.place(relx=0.33, rely=0.34)
        # self.multiple_num_rad2.place(relx=0.66, rely=0.34)
        # # 电流类型
        # self.voltage_type_label.place(relx=0.1, rely=0.39)
        # self.voltage_type_rad1.place(relx=0.33, rely=0.39)
        # self.voltage_type_rad2.place(relx=0.66, rely=0.39)
        # # 电压峰值
        # self.peak_voltage_entry_label.place(relx=0.05, rely=0.53)
        # self.peak_voltage_entry.place(relx=0.3, rely=0.52)
        # # 标称网电源电压
        # self.supply_voltage_entry_label.place(relx=0.05, rely=0.63)
        # self.supply_voltage_entry.place(relx=0.53, rely=0.62)
        # # 海拔
        # self.altitude_entry_label.place(relx=0.46, rely=0.53)
        # self.altitude_entry.place(relx=0.66, rely=0.52)
        # # 开始计算按键
        # self.calbtn.place(relx=0.68, rely=0.63)
        # self.address.pack(side="left",anchor='s')
        # # 计算结果显示窗
        # self.cal_voltage_label.place(relx=0.05, rely=0.75)


    def ClickCalButton(self):
        pollution_class = self.pollution_class_var.get()
        material = self.material_var.get()
        object_type = self.object_type_var.get()
        place_type = self.place_type_var.get()
        multiple_num = self.multiple_num_var.get()
        voltage_type = self.voltage_type_var.get()
        peak_voltage = float(self.peak_voltage_entry.get())
        supply_voltage = float(self.supply_voltage_entry.get())
        altitude = float(self.altitude_entry.get())
            
        ElecClearance, CreepDist = calculate_distance(pollution_class, material, object_type, place_type, multiple_num, voltage_type, peak_voltage, supply_voltage, altitude)
        TestVoltage = calculate_voltage(object_type, place_type, multiple_num, voltage_type, peak_voltage)
        cal_result = f"试验电压：{TestVoltage} {'V' if type(TestVoltage) != str else ''}; \n爬电距离：{CreepDist} mm; 电气间隙：{ElecClearance} mm"

        self.cal_voltage_label.configure(text="")   # 清空
        self.cal_voltage_label.configure(text=cal_result, fg='red')

    
    def ClickLinkButton(self):
        webbrowser.open('https://gitee.com/deng-guifeng/test-voltage-calculator/tree/master')


